#include <frame.h>


/*
 * Инициализирует карту физической памяти 
 * на основе данных полученных от BIOS
 */
uint32 init_frame_mem(acpi_mem_map_t *mem_map, uint32 map_size, frame_t *frame_map){
	uint32 i, indx = 0;
	//Первый мегабайт памяти зарезервирован
	while(indx * 4096 < 0x100000){
		frame_map[indx].reserved = 1;
		indx++;
	}
	
	uint32 start = 0, end = 0, old_indx = indx;
	for(i = 0; i < map_size; i++){
		if(mem_map[i].start >= 0x100000){
			start = mem_map[i].start;
			kprintf("start: %X end: %X\n", start, end);
			if(old_indx < indx && start != end){
				//kprintf("Break!, indx = %i\n", indx);
				break;
			}
			//kprintf("Continue\n");
			end = mem_map[i].start + mem_map[i].length;
			kprintf("start2: %X end: %X\n", start, end);
			while(indx * 4096 < end){
				//kprintf("ind: %X, end: %X\n", indx*4096, end);
				if(mem_map[i].type == 1){
					frame_map[indx].reserved = 0;
					frame_map[indx].in_use = 0;
				}else{
					frame_map[indx].reserved = 0;
				}
				indx++;
			}
		}
	}
	return indx;
}

frame_t * _allocFrame(uint32 fn){
	static uint32 i = 0;
	uint32 ret;
	//kprintf("si: %i; ", i);
	
	while(frame_map[i].reserved){
		i++;
	}
	ret = i;
	fn = i + fn;
	while(i < fn){
		frame_map[i].reserved = 1;
		i++;
	}
	//kprintf("i: %i; ", i);
	return &frame_map[ret];
}
//
void * allocFrame(uint32 fn){
	frame_t *frm = _allocFrame(fn);
	void *pg = (void *)((frm - frame_map) << 12);
	//kprintf("frm:%X, page: %X\n", frm, pg);
	return pg;
}

inline int
memcp(void *src, void *dst, uint32 sz){
	asm("movl %0, %%esi"::"r" ((uint32)src):"%eax");
	asm("movl %0, %%edi"::"r" ((uint32)dst):"%eax");
	asm("movl %0, %%ecx"::"r" (sz):"%eax");
	asm("rep movsb;");
}

